/**
 * @author Nicolas Latorre
 */

import org.junit._
import org.junit.Assert._
import com.meterware.servletunit.ServletRunner
import com.meterware.httpunit.PostMethodWebRequest
import com.meterware.httpunit.GetMethodWebRequest
import com.meterware.httpunit.WebRequest
import com.meterware.servletunit.ServletUnitClient
import com.meterware.httpunit.WebResponse
import sa4.UsiAdsServlet
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServletRequest
import sa4.persistence._

class testUsiAdsServlet {

  //Testing the form
  val ss = new ServletRunner()
  ss.registerServlet("", classOf[UsiAdsServlet].getName)

  @Test
  def testFormGet {
    val sc: ServletUnitClient = ss.newClient()
    val request: WebRequest = new GetMethodWebRequest("http://localhost/")
    val response: WebResponse = sc.getResponse(request)
    assertNotNull("No response received", response)
  }

  @Test
  def testFormSubmit {
    val sc: ServletUnitClient = ss.newClient()

    // Ask for the form -- this installs the handler
    {
      val request: WebRequest = new GetMethodWebRequest("http://localhost/newUser")
      val response: WebResponse = sc.getResponse(request)
      assertNotNull("No response received", response)
      val xml = scala.xml.XML.loadString(response.getText)
      assertTrue((xml \\ "form" \ "@action").text == "/postData")
    }

    // Submit the form.
    {
      val theUsername = "George Orwell"
      val theName = "George."
      val theMail = "george@orwell.com"
      val thePass = "1234"
      val thePhone = "091"

      val request: WebRequest = new PostMethodWebRequest("http://localhost/postComment")
      request.setParameter("userName", theUsername)
      request.setParameter("name", theName)
      request.setParameter("email", theMail)
      request.setParameter("pass", thePass)
      request.setParameter("number", thePhone)

      val response: WebResponse = sc.getResponse(request)
      assertNotNull("No response received", response)
      val xml = scala.xml.XML.loadString(response.getText)
      assertTrue((xml \\ "p").text contains ("Welcome to the Usi Ads World"))
    }
  }

  @Test
  def test404 {
    val sc: ServletUnitClient = ss.newClient()
    sc.setExceptionsThrownOnErrorStatus(false)

    val request: WebRequest = new GetMethodWebRequest("http://localhost/fjklsdjdkl")
    val response: WebResponse = sc.getResponse(request)
    assertTrue(response.getResponseCode == 404)
  }

  //Testing the Routing
  @Test
  def testNotExistingRoute {
    val sv: ServletUnitClient = ss.newClient()
    sv.setExceptionsThrownOnErrorStatus(false)
    //check that no "/test" route exists
    val request: WebRequest = new GetMethodWebRequest("http://localhost/test")
    val response: WebResponse = sv.getResponse(request)
    assertTrue(response.getResponseCode == 404)
  }
  @Test
  def testAddRouteMethod {
    val sv: ServletUnitClient = ss.newClient()
    sv.setExceptionsThrownOnErrorStatus(false)
    //check that no "/test" route exists
    val request: WebRequest = new GetMethodWebRequest("http://localhost/test")
    val response: WebResponse = sv.getResponse(request)
    //add the "/test" route to the routeTable and test that now exists
    val s = new UsiAdsServlet
    def f(req: HttpServletRequest, res: HttpServletResponse) = println("testing...")
    s.routing.addRoute("/test", f)
    assertNotNull("No response received", response)
  }

  @Test
  def testRemoveRoute {
    val sv: ServletUnitClient = ss.newClient()
    sv.setExceptionsThrownOnErrorStatus(false)
    //Add and then Remove /test route
    val s = new UsiAdsServlet
    def f(req: HttpServletRequest, res: HttpServletResponse) = println("testing...")
    s.routing.addRoute("/test", f)
    s.routing.removeRoute("/test")
    val request: WebRequest = new GetMethodWebRequest("http://localhost/test")
    val response: WebResponse = sv.getResponse(request)
    assertTrue(response.getResponseCode == 404)
  }

  @Test
  def testClearTableMethod {
    val sv: ServletUnitClient = ss.newClient()
    sv.setExceptionsThrownOnErrorStatus(false)
    val request: WebRequest = new GetMethodWebRequest("http://localhost/test")
    val response: WebResponse = sv.getResponse(request)
    //test the clearTable method
    val s = new UsiAdsServlet
    s.routing.clearRouteTable
    assertTrue(response.getResponseCode == 404)
  }
  //Testing Template

  @Test
  def testTemplate {
    val sv: ServletUnitClient = ss.newClient()
    val request: WebRequest = new GetMethodWebRequest("http://localhost/newUser")
    val response: WebResponse = sv.getResponse(request)
    val responseXML = (scala.xml.XML.loadString(response.getText) \\ "h1").text
    val s = new UsiAdsServlet
    val xml = (s.template.loadPage("index.html") \\ "h1").text
    assertTrue(xml.equals(responseXML))
  }

  //Testing Session

  @Test
  def testSession {
    val sv: ServletUnitClient = ss.newClient()
    var request: WebRequest = new GetMethodWebRequest("http://localhost/")
    var response: WebResponse = sv.getResponse(request)

    request = new GetMethodWebRequest("http://localhost/")
    response = sv.getResponse(request)

    val responseXML = (scala.xml.XML.loadString(response.getText) \\ "div").text
    Thread.sleep(5000)
    var request1: WebRequest = new GetMethodWebRequest("http://localhost/")
    var response1: WebResponse = sv.getResponse(request1)
    val responseXML1 = (scala.xml.XML.loadString(response1.getText) \\ "div").text

    assertTrue(responseXML1 != 1)
  }

  //Testing Persistence
  @Test
  def testPersistence {
    val sv: ServletUnitClient = ss.newClient()
    var request: WebRequest = new GetMethodWebRequest("http://localhost/")
    var response: WebResponse = sv.getResponse(request)
    val s = new UsiAdsServlet
    //s.persistence.newAccount("foobar","1000")
    s.persistence.newUser("Nicolas", "Nik", "nic@las.nn", "1234", "091")
    assertTrue(s.persistence.getUsers.size == 3)
    s.persistence.newUser("Giuseppe", "Giuse", "giuseppe@dj.gg", "1234", "091")
    assertTrue(s.persistence.getUsers.size == 4)
  }
}
